/**
 * 
 *  @project Air Traff Monitor
 * 
 *  @author M.Emre ATASEVER <m.emre.atas@gmail.com>
 *  @author M.Burak ALKAN <mburakalkan@gmail.com>
 *  @author H.Burak KARAMIK <bkaramik@gmail.com>
 *
 *	`Air Traffic Monitor' is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */


#ifndef  NETITEM_INC
#define  NETITEM_INC

#include <QList>
#include <QVariant>
#include <QColor>
#include <QPair>
#include "kisock.h"

struct NetworkRootItem;
class ClientItem;

class NetmodelItem
{
public:
	virtual ~NetmodelItem(){};
	virtual int	row()			= 0;
	virtual void*	parent()		= 0;
	virtual int	rowCount()		= 0;
	virtual QVariant data(int column)	= 0;
	
	QColor 	color;
	bool 	hasColor;
};

template<typename Parent,typename Item>class NetmodelData: public NetmodelItem
{
public:
	NetmodelData(Parent *parent)
	{
		parentItem	= parent;
		maxlat	= maxlon	= maxalt	=
	      	bestlat	= bestlon	= bestalt	=
	      	minlat	= minlon	= minalt	= 
		minspd	= maxspd	= 0;
		agglat	= agglon	= aggalt	= 
		maxrate	= 0;
		firsttime	= lasttime	= 0;
		datapackets	= cryptpackets	=
		weakpackets	= quality	= 
		signal	= noise	= bestquality	=
		bestsignal	= bestnoise	=
		type	= gpsfixed	= maxseenrate	=
		aggpoints	= manufscore	= 
		decrypted	= wep	= atype	= 
		encodingset	= datasize	= 0;	
	};
	virtual ~NetmodelData(){};
	virtual void* getPointer(int field,Item *item,int *type,bool remap = false)	= 0;
	int row()
	{
		return parentItem->items.indexOf((Item*)this);
	};

	void* parent()
	{
		return parentItem;
	}
	void setData(networkInfo *data)
	{

		int j = data->props.size();
		int type;
		for(int i = 1;i<j;i++)
		{
			void *value	= getPointer(data->idx->at(i),(Item*)this,&type);
			switch(type)
			{
				case 0:
				case 4:
				case 5:
				case 6:
					*((int*)value)	= data->props[i].toInt();
					continue;
				case 1:
					*((QString*)value)	= data->props[i].toString();
					continue;
				case 2:
					*((float*)value)	= data->props[i].toDouble();
					continue;
				case 3:
					*((double*)value)	= data->props[i].toDouble();
					continue;
				case 7:
					*((qint64*)value)	= data->props[i].toLongLong();
					continue;
			}
				
		}
	};
	QVariant data(int column)
	{
		if(column == 0)
			return bssid;
		else
		{
			int type;
			void* value	= getPointer(column,(Item*)this,&type,true);
			switch(type)
			{
				case 0:
				case 4:
				case 5:
				case 6:
					return QVariant(*((int*)value));
				case 1:
					return QVariant(*((QString*)value));
				case 2:
					return QVariant(*((float*)value));
				case 3:
					return QVariant(*((double*)value));
				case 7:
					return QVariant(*((qint64*)value));
				case 8: 
					return QVariant();
			}
		}
		return QVariant();
	};
	QString bssid;
protected:
	Parent* parentItem;

	float	maxlat, maxlon, maxalt, 
	      	bestlat, bestlon, bestalt, 
	      	minlat, minlon, minalt, minspd, 
	      	maxspd; 
	double	agglat, agglon, aggalt;
	double	maxrate;
	time_t	firsttime, lasttime;
	int	datapackets,cryptpackets,
		weakpackets,quality,signal,noise,bestquality,
		bestsignal,bestnoise;
	int	type,gpsfixed,maxseenrate;
	long	aggpoints;
	int	manufscore,decrypted,wep,atype,encodingset;
	unsigned long datasize;	
	QString rangeip,manufkey;  
};

class NetworkItem : public NetmodelData<NetworkRootItem,NetworkItem>
{
public:
	NetworkItem(networkInfo *data,NetworkRootItem *parent);
	~NetworkItem();

	int rowCount();
	ClientItem*	addClient(clientInfo *info);
	
	QList<ClientItem*> items;
	//FIXME: 
private:
	int	llcpackets,dupeivpackets;
	int 	channel;
	int 	turbocellnid,turbocellmode,turbocellsat;
	int 	cloaked,beaconrate,octets,carrierset;
	qint64 	bsstimestamp;
	QString	ssid,beaconinfo;

	void* getPointer(int field,NetworkItem *item,int *type,bool remap = false);
};

struct NetworkRootItem
{
	public:
		QList<NetworkItem*> items;
};

class ClientItem : public NetmodelData<NetworkItem,ClientItem>
{
public:
	ClientItem(clientInfo *info,NetworkItem *parent);

	//Mac address is stored in Netmodeldata::bssid
	QString parentbssid;
	int rowCount();
private:
	void* getPointer(int field,ClientItem *item,int *type,bool maptonet = false);
};
#endif
